package com.abel.bigwater.dataserver.model.qdies

import com.abel.bigwater.data.BcdString
import io.netty.buffer.Unpooled
import org.junit.Assert.assertEquals
import org.junit.Test
import org.slf4j.LoggerFactory
import java.util.*

class MainPacketTest {
    @Test
    fun fillAskMeterConfig() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskMeterConfig
            data = MainAskMeterConfigData()

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_METER_CONFIG, str)
    }

    @Test
    fun fillAsk485Config() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Ask485Config
            data = MainAsk485ConfigData().also { it.internalAddr = 1 }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals("ask 485 config", DEMO_ASK_485_CONFIG, str)
    }

    @Test
    fun fillAskAnalogConfig() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskAnalogConfig
            data = MainAskAnalogConfigData().also { it.internalAddr = 8 }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_ANALOG_CONFIG, str)
    }

    @Test
    fun fillAskPulseConfig() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskPulseConfig
            data = MainAskPulseConfigData().also { it.internalAddr = 11 }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_PULSE_CONFIG, str)
    }

    @Test
    fun fillSetMeterConfig() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetMeterConfig
            data = MainSetMeterConfigData().also {
                it.rs485Config = BitSet(8).also {
                    for (i in 0..4) it[i] = true
                }

                it.analogConfig = BitSet(8).also {
                    for (i in 0..4) it[i] = true
                }

                it.pulseConfig = BitSet(8).also {
                    for (i in 0..3) it[i] = true
                }
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_METER_CONFIG, str)
    }

    @Test
    fun fillConfig485() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Config485
            data = MainConfig485Data().also {
                it.internalAddr = 1
                it.addr485 = 25
                it.readMode = ReadModeType.WeekMode
                it.uploadStart = BcdString(byteArrayOf(2, 8), true)
                it.volt = 12
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals("config rs485", DEMO_CONFIG_485, str)
    }

    @Test
    fun fillConfigAnalog() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.ConfigAnalog
            data = MainConfigAnalogData().also {
                it.internalAddr = 11
                it.rangeHigh = 2000F
                it.rangeLow = 0F
                it.warnHigh = 1600F
                it.warnLow = 0F

                it.readMode = ReadModeType.DayMode
                it.uploadStart = BcdString(byteArrayOf(0, 7), true)
                it.samplePeriod = 0
                it.uploadPeriod = 0

                it.volt = 12
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals("config analog", DEMO_CONFIG_ANALOG, str)
    }

    @Test
    fun fillConfigPulse() {
        val buf = Unpooled.buffer()
        val p = MainPacket().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.ConfigPulse
            data = MainConfigPulseData().also {
                it.internalAddr = 11
                it.readMode = ReadModeType.DayMode
                it.uploadStart = BcdString(byteArrayOf(3, 15), true)
                it.samplePeriod = 120
                it.uploadPeriod = 3
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals("config pulse", DEMO_CONFIG_PULSE, str)
    }

    companion object {
        private val lgr = LoggerFactory.getLogger(MainPacketTest::class.java)

        const val DEMO_ASK_METER_CONFIG = "681200000111007416"

        const val DEMO_ASK_485_CONFIG = "68120000011301017016"

        const val DEMO_ASK_ANALOG_CONFIG = "68120000011501086716"

        const val DEMO_ASK_PULSE_CONFIG = "681200000117010b6216"

        const val DEMO_SET_METER_CONFIG = "681200000110041f1f0f002416"

        const val DEMO_CONFIG_485 = "6812000001121501000000000000001901010101030202080000000c2516"

        const val DEMO_CONFIG_ANALOG = "681200000114190b0144fa00000000000044c80000000000000100070000000cee16"

        const val DEMO_CONFIG_PULSE = "681200000116070b010315007803c916"
    }
}